/*
Copyright 2011 Raymond Giorgi

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */

package edu.pitt.cs3530.regression;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import edu.pitt.cs3530.configuration.FrontEndConfiguration;
import edu.pitt.cs3530.controllers.PredictorListener;
import edu.pitt.cs3530.misc.Mutexs;
import edu.pitt.cs3530.predictors.MovingAverageThread;
import edu.pitt.cs3530.predictors.PredictorThread;
import edu.pitt.cs3530.regression.TimeStamp.SecMSec;

public class MovingAverageTest implements PredictorListener {

	BufferedWriter writer = null;

	public MovingAverageTest(String directory) throws IOException,
			InterruptedException {
		for (File file : (new File(directory)).listFiles()) {
			file.delete();
		}
		long timeToKeep = FrontEndConfiguration.getInstance()
				.getTimeToKeepRequests();
		long utilToKeep = FrontEndConfiguration.getInstance()
				.getUtilizationToKeep();
		long sleepTime = FrontEndConfiguration.getInstance()
				.getPredictorSleepTime();
		writer = new BufferedWriter(new FileWriter("tmpMA.dat"));
		PredictorThread thread = new MovingAverageThread(directory, 5 * 1000,
				timeToKeep, (int) utilToKeep, sleepTime);
		thread.addListener(this);
		thread.start();
		List<String> fileNames = new LinkedList<String>();
		fileNames.addAll(getTestOne(directory, 10));

		Random rand = new Random();

		for (int i = 0; i < 50; i++) {
			writeFiles(getTestOne(directory, 5));
			sleep(200);
		}

		writer.close();
		thread.stop();
	}

	public static void main(String args[]) {
		String directory = "./";
		if (args.length > 0) {
			directory = args[0];
		}
		try {
			new MovingAverageTest(directory);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void alertChange(PredictorThread predictor) {
		System.out.println("Current load: ");
		System.out.println("\t" + predictor.currentLoad());
		System.out.println("\t" + predictor.currentSlope());
		try {
			writer.write("\t"
					+ predictor.predictedChange(FrontEndConfiguration
							.getInstance().getTimeToKeepRequests()) + "\r\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void writeFiles(List<String> fileNames) throws IOException {
		FileWriter fw = null;
		BufferedWriter bw = null;
		Mutexs.lockFileMutex();
		for (String fileName : fileNames) {
			long time = System.currentTimeMillis();
			fw = new FileWriter(fileName);
			bw = new BufferedWriter(fw);
			bw.write("");
			bw.close();
		}
		writer.write("" + fileNames.size() + ":\r\n");
		Mutexs.unlockFileMutex();
	}

	public static List<String> getTestOne(String directory, int numberToProduce) {
		List<String> fileNames = new LinkedList<String>();
		Random rand = new Random();
		String fileName = "";
		for (int i = 0; i < numberToProduce; i++) {
			SecMSec secMSec = TimeStamp.createSecUSec();
			fileName = directory + "fin-" + secMSec.getSec() + "-"
					+ getRandomUSec(secMSec.getMSec()) + "-";
			long finSec = secMSec.getSec() + Math.abs(rand.nextInt() % 3);
			long finMSec = secMSec.getMSec() + Math.abs(rand.nextInt() % 100);
			if (finMSec > 999) {
				finMSec -= 1000;
			}
			fileName += finSec + "-" + getRandomUSec(finMSec);
			fileNames.add(new String(fileName));
			// try {
			// Thread.sleep(Math.abs(rand.nextLong() % 1000));
			// } catch (InterruptedException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// }
			fileName = "";
		}
		return fileNames;
	}

	public static long getRandomUSec(long mSec) {
		return (mSec * 1000) + Math.abs((new Random()).nextLong() % 1000);
	}

	public void sleep(long milliseconds) {
		try {
			Thread.sleep(milliseconds);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
